package com.habdqn.studentmanager.handler;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.habdqn.studentmanager.bean.AttendanceRecord;
import com.habdqn.studentmanager.bean.Student;
import com.habdqn.studentmanager.constant.ConnState;
import com.habdqn.studentmanager.constant.Constant;
import com.habdqn.studentmanager.util.AttendanceConnection;
import com.habdqn.studentmanager.util.ConfigUtil;
import com.habdqn.studentmanager.util.DateUtil;
import com.habdqn.studentmanager.util.FileUtil;
import com.habdqn.studentmanager.util.ProjectUtil;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @author Fan
 * 
 *         2017年7月4日
 * 
 */
public class AttendanceHandler extends ChannelInboundHandlerAdapter {

	private static final Logger logger = LoggerFactory.getLogger("AttendanceConnection");

	/**
	 * 本次连接对象
	 */
	private AttendanceConnection connection;

	public AttendanceHandler(AttendanceConnection connection) {
		this.connection = connection;
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
		// 连接成功
		connection.setStatus(ConnState.SUCCESS.toInt());
		logger.info("与考勤机连接成功.");
		connection.clearReConnCount();
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

		ByteBuf buf = (ByteBuf) msg;
		// 取出类型
		int type = buf.readInt();
		byte[] tmp = new byte[buf.readableBytes()];
		buf.readBytes(tmp);

		Date now = new Date();
		String attNumStr = new String(tmp, Constant.UTF8);
		
		switch (type) {
		case 0:
			test(tmp, ctx);
			break;
		case 1:
			record(attNumStr, now);
			break;
		default:
			logger.debug("未知消息:{}, 断开连接", type);
			ctx.close();
		}

	}

	/**
	 * 返回接头信息
	 * @param tmp
	 * @param ctx
	 */
	private void test(byte[] tmp, ChannelHandlerContext ctx) {
		logger.debug("测试消息");
		
		ByteBuf buf = Unpooled.buffer();
		buf.writeInt(8);
		buf.writeInt(0);
		buf.writeBytes(tmp);
		ctx.writeAndFlush(buf);
	}
	
	/**
	 * 记录考勤记录
	 * @param attNumStr
	 * @param date 考勤时间
	 */
	private void record(String attNumStr, Date date) {
		logger.debug("考勤消息:{} {}", attNumStr, date);
		
		try {
			Integer attNum = Integer.valueOf(attNumStr);

			AttendanceRecord record = new AttendanceRecord();
			Student stu = new Student();
			stu.setInnerId(attNum);
			record.setStudent(stu);
			record.setAttDate(date);
			record.setCreateDate(new Date());
			
			connection.getAttendanceService().addRecord(record, true);
		}
		catch (RuntimeException e) {
			logger.error("记录考勤记录异常", e);
			
			String fileName = DateUtil.format(date, DateUtil.FormatStr10) + ".cvs";
			String path = ProjectUtil.getHomePath() + ConfigUtil.getKey("attendanceLog") + fileName;
			// 失败记录文件
			FileUtil.startCreateFile().path(path).open()
			        .writeln(attNumStr + " " + DateUtil.format(date, DateUtil.FormatStr19)).close();
		}
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		super.exceptionCaught(ctx, cause);
		logger.error("与考勤机通信发生异常.", cause);
		// 断开
		connection.setStatus(ConnState.DISCONNECT.toInt());
	}

	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		super.channelUnregistered(ctx);
		logger.info("考勤机主动断开连接.");
		// 断开
		connection.setStatus(ConnState.DISCONNECT.toInt());
		ctx.close();
	}

}
